#include <boost/lexical_cast.hpp>
#include "logging/logging.hpp"
#include "common/daemon/daemonize.hpp"
#include "ConfigMap.hpp"
#include "Stats_ServerOptions.hpp"
#include "components/encrypt/utils.hpp"
#include "components/service/mcast_service_process.hpp"
#include "components/application/stats_mcast_server.hpp"

int main(int argc, char* argv[])
{
    try{
        ConfigMap server_config(new Stats_ServerOptions,"stats_server.ini",argc,argv);
        init_log(argv[0],server_config["log.path"].get_string());
        LOG(INFO)<<server_config;

        LOG(INFO)<<"Forced debug run.";
        server_config.set("debug",1);
        if(!server_config["debug"].get_int())
            daemonize();
        ba::io_service ios;
        crypto_buf_t iv=HexDecodeString(server_config["encrypt.iv"].get_string().c_str());
        crypto_buf_t key=HexDecodeString(server_config["encrypt.key"].get_string().c_str());
        endpoint conf_local_if=server_config["net.local_if"].get_endpoint();
        endpoint mgroup=server_config["net.mgroup"].get_endpoint();

        udp_endpoint_t local_if(ba::ip::address::from_string(conf_local_if.address),0);
        udp_endpoint_t mcast_group(ba::ip::address::from_string(mgroup.address),mgroup.port);
        int ttl=server_config["net.ttl"].get_int();

        bt::seconds persist_interval(server_config["persist.interval"].get_int());
        bt::minutes expected_lifetime(server_config["persist.age"].get_int());
        std::string persist_path(server_config["persist.path"].get_string());
        int threads=server_config["system.threads"].get_int();
        std::string cluster(server_config["net.cluster"].get_string());
        std::string node(server_config["net.node"].get_string());

        stats_mcast_server Server(ios,local_if,mcast_group,ttl,iv,key,persist_interval,expected_lifetime,persist_path,threads,cluster,node);

        Server.run();
        sleep(100);
        Server.shutdown();
    }
    catch(std::exception const& e)
    {
        LOG(ERROR)<<__FUNCTION__<<" "<<e.what();
    }
    return 0;
}
